home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Entertainment
/
tblt
/
tblt⁄record.c
< prev
next >
Wrap
Text File
|
1986-09-06
|
5KB
|
192 lines
/*
* record.c - move recording/playback for the game of Tablut
*/
#include <quickdraw.h>
#include <window.h>
#include <memory.h>
#include "progerr.h"
#include "tablut.h"
#define BT_NOBODY 0
#define BT_SWEDE 1
#define BT_MUSC 2
#define BT_KING 3
#define BT_NOWIN 0
#define BT_WHITEWIN 1
#define BT_BLACKWIN 2
#define STATEBITS 2 /* bits required to store any BT_ value */
#define STATEMASK 3 /* mask to extract adjusted STATEBITS */
#define BITSPERBYTE 8 /* number of bits per byte */
struct moveblock *bdblockp; /* pointer to the current memory chunk */
char *bdmovep; /* pointer to the current state in that chunk */
/*
* initmoves() - setup the move-recording structures (called only once).
*/
initmoves()
{
curmove = 0;
nummoves = 0;
bdblockp = &firstblock;
bdblockp->nxtblk = (struct moveblock *) 0;
bdmovep = &(bdblockp->bytes[0]);
}
/*
* seekboard() - seek to the given move number in the game.
*/
seekboard(n)
int n; /* the move number to go to */
{
int blk; /* the chunk index of the move */
int idx; /* the move index within that chunk */
if (n >= nummoves) n = nummoves - 1;
if (n < 0) n = 0;
blk = n / BDPERBLK;
idx = n % BDPERBLK;
for (bdblockp = &firstblock; blk > 0; --blk) {
bdblockp = bdblockp->nxtblk;
}
bdmovep = &(bdblockp->bytes[BOARDBYTES * idx]);
curmove = n;
}
/*
* readboard() - read the board state from the current position in
* the record.
*/
readboard()
{
int pidx; /* temp piece-index */
int kidx, sidx, midx; /* king, swede, and muscovite indices */
int h,v; /* coords */
char *curbyte; /* current byte within the move record */
int bits; /* bits representing a grid's state */
int bitshift; /* shift required to extract "bits" */
for (pidx = 0; pidx < NUMPIECES; ++pidx) {
hidepiece(pidx); /* hide 'em so they move instantaneously */
}
kidx = THEKING;
sidx = FIRSTSWEDE;
midx = FIRSTMUSC;
curbyte = bdmovep;
bitshift = 0;
for (h = -4; h <= 4; ++h) {
for (v = -4; v <= 4; ++v) {
bits = ((int)(*curbyte) >> bitshift) & STATEMASK;
switch (bits) {
case BT_KING:
if (kidx <= THEKING) placepiece(kidx++, h, v);
break;
case BT_SWEDE:
if (sidx <= LASTSWEDE) placepiece(sidx++, h, v);
break;
case BT_MUSC:
if (midx <= LASTMUSC) placepiece(midx++, h, v);
break;
}
if ((bitshift += STATEBITS) >= BITSPERBYTE) {
bitshift = 0;
++curbyte;
}
}
}
while (midx <= LASTMUSC) removepiece(midx++);
while (sidx <= LASTSWEDE) removepiece(sidx++);
while (kidx <= THEKING) removepiece(kidx++);
bits = ((int)(*curbyte) >> bitshift) & STATEMASK;
switch(bits) {
case BT_WHITEWIN: winner = WHITEWIN; setsetup(1); break;
case BT_BLACKWIN: winner = BLACKWIN; setsetup(1); break;
default: winner = NOWIN; break;
}
advmove(0); /* advance the record without setting EOF */
}
/*
* writeboard() - save the current state of the game.
*/
writeboard()
{
int h,v; /* coords */
char *curbyte; /* current byte within a move record */
int bits; /* bits representing a grid's state */
int bitshift; /* shift required to set "bits" */
char *malloc();
if (bdmovep >= &(bdblockp->bytes[BOARDBYTES * BDPERBLK])) {
/* allocate a new chunk of memory for recording */
if (!(bdblockp->nxtblk =
(struct moveblock *) malloc(sizeof(struct moveblock)))) {
progstop(PE_NOMEM);
bomb();
}
bdblockp = bdblockp->nxtblk;
bdblockp->nxtblk = (struct moveblock *) 0;
bdmovep = &(bdblockp->bytes[0]);
}
curbyte = bdmovep;
bitshift = 0;
for (h = -4; h <= 4; ++h) {
for (v = -4; v <= 4; ++v) {
bits = BT_NOBODY;
if ((*gridp)[h][v]) {
switch(classbase((*gridp)[h][v])) {
case FIRSTSWEDE: bits = BT_SWEDE; break;
case FIRSTMUSC: bits = BT_MUSC; break;
case THEKING: bits = BT_KING; break;
}
}
if (bitshift == 0) {
*curbyte = (char) 0;
}
*curbyte |= (char)(bits << bitshift);
if ((bitshift += STATEBITS) >= BITSPERBYTE) {
bitshift = 0;
++curbyte;
}
}
}
bits = BT_NOWIN;
switch(winner) {
case WHITEWIN: bits = BT_WHITEWIN; setsetup(1); break;
case BLACKWIN: bits = BT_BLACKWIN; setsetup(1); break;
}
if (bitshift == 0) {
*curbyte = (char) 0;
}
*curbyte |= (char)(bits << bitshift);
ischanged = 1;
advmove(1); /* advance, setting EOF */
}
/*
* advmove() - advance the record one move, optionally setting EOF
*/
advmove(seteof)
int seteof; /* if TRUE, the new state is the end one */
{
bdmovep += BOARDBYTES;
if (bdmovep >= &(bdblockp->bytes[BOARDBYTES * BDPERBLK])) {
if (bdblockp->nxtblk) {
bdblockp = bdblockp->nxtblk;
bdmovep = &(bdblockp->bytes[0]);
}
}
++curmove;
if (seteof) {
nummoves = curmove;
}
fixlooker();
drawstate();
}